<?php
/**
 * Created by PhpStorm.
 * User: 我型我素
 * Date: 2018/1/15
 * Time: 14:38
 */

namespace App\Services\Orders;


use App\Services\Common\BaseService;
use App\Services\Goods\GoodsService;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Redis;
use Symfony\Component\HttpKernel\Exception\HttpException;
use Webpatser\Uuid\Uuid;

class OrderQueueService extends BaseService
{
    protected $goodsService;
    protected $queue_key;
    protected $queue_code;
    public function __construct(GoodsService $goodsService)
    {
        $this->goodsService = $goodsService;
        $this->queue_key = "order_queue";
        $this->queue_code = "order_queue_user_";
    }


    /**
     * 加入到订单队列
     * @param $userId
     */
    public function addOrderQueue($userId){
        //清除已存在队列的元素，重新排队
        $queue_code = $this->queue_code.$userId;
        $this->removeQueue($this->queue_key,$queue_code);

        //进入队列并且缓存用户信息
        $time_out = 30/60;
        $this->addQueue($this->queue_key,$queue_code,$time_out);
    }

    /**
     * 加入到队列
     * @param $queue_key
     * @param $queue_code
     * @param $time_out
     */
    public function addQueue($queue_key,$queue_code,$time_out){
        Redis::rpush($queue_key,$queue_code);
        Cache::put($queue_key.'_'.$queue_code,$queue_code,$time_out);
    }

    /**
     * 从队列中去掉指定的元素
     * @param $key
     * @param $queue_code
     */
    public function removeQueue($key,$queue_code){
        Redis::lrem($key,0,$queue_code);
        Cache::forget($key.'_'.$queue_code);
    }

    /**
     * 从队列中去掉第一个元素
     * @param $key
     */
    public function lpopQueue($key){
        Redis::lpop($key);
    }

    /**
     * @author yangzhic
     * @return int|string
     * @throws \Exception
     */
    public function getOrderQueueCode(){
        $code = time();
        $ranstr = Uuid::generate(3,'test', Uuid::NS_DNS);
        $code .= $ranstr;
        return $code;
    }

    /**
     * 检查订单队列
     * @author yangzhic
     * @param $param
     * $param = ['user_id','best_time']
     */
    public function checkOrderQueue($param){
        $queue_code = $this->queue_code.$param['user_id'];
        $this->addOrderQueue($param['user_id']);
        try{
            $flag = true;
            while($flag){
                $code = Cache::get($this->queue_key.'_'.$queue_code);
                if(!empty($code)){
                    $current_order_list = Redis::lrange($this->queue_key,0,0);
                    if($code == $current_order_list[0]){
                        $flag=false;
                        //检查库存
                        $this->goodsService->checkQueueOrderGoodsStock($param);

                        $this->removeQueue($this->queue_key,$queue_code);
                    }else{
                        usleep(200000); //延迟0.2秒后执行
                    }
                }else{
                    $flag=false;
                    $this->removeQueue($this->queue_key,$queue_code);
                    throw new HttpException('500','订单提交超时，请重新提交订单');
                }
            }
        }catch (\Exception $e){
            $this->removeQueue($this->queue_key,$queue_code);

            if($e->getCode()!=500){
                throw new HttpException('500','订单提交失败，请重新提交订单');
            }
        }
    }

}